/**
 * \file
 *          teleMainBL.cpp
 * \brief
 *          Implements starter of entTelematicsMain
 *
 * \par Author (last changes):
 *          - Song Yang
 *          - Phone +65 65800179
 *          - Continental Automotive Singapore
 * \par Project Leader:
 *          - Mandy Sin
 *          - Phone +65 67799 819
 *          - Mandy.Sin@continental-corporation.com
 * \par Responsible Developer:
 *          - Song Yang
 *          - Phone +65 65800179
 *          - Continental Automotive Singapore
 * \par Responsible Architect:
 *          - Goh Hoe Chun
 *          - Phone +65 67799 586
 *          - Hoe.Chun.Goh@continental-corporation.com
 *
 * \par Project:
 *      DPCA2
 *
 * \par SW-Component:
 *      teleMainBL
 *
 * \par SW-Package:
 *      Telematics Main
 *
 * \par SW-Module:
 *      Telematics Main
 *
 * \par SW-Architecture Specification:
 *      DPCA_SW_AD_IMX
 *      003
 *
 * \par SW-Design Specification:
 *      DPCA_your_module_SW_DD
 *      your_doc_number
 *
 * \par SW-Test Case Specification:
 *      DPCA_your_module_SW_TS
 *      your_doc_number
 *
 * \par CM-Info:
 *      - teleMainBL.cpp-1:incl:DPCARSgp#1
 *      - uidc1282
 *
 * \note
 *      This is a note.
 *
 * \bug
 *      - there are no known bugs
 *
 * \par Module-History:
 *
 * \verbatim
 * Date                Author                 Reason
 * 20 Dec 2012         Song Yang           Initial Creation
 * The latest entry at the head of the history list.
 * \endverbatim
 *
 * \par Copyright Notice:
 * Copyright (C) 2011 Continental Automotive Singapore Pte Ltd.
 * Alle Rechte vorbehalten. All Rights Reserved.\n
 * The reproduction, transmission or use of this document or its contents is
 * not permitted without express written authority.\n
 * Offenders will be liable for damages. All rights, including rights created
 * by patent grant or registration of a utility model or design, are reserved.
 *
 * \ingroup GEN_TELE_MAIN
 */
     
#include "teleMainBL.h"
#include "teleGenHMIMsgHandler.h"
#include "tlmServiceMsgHandler.h"
#include "teleLogTrace.h"
#include "teleMainBLRpcSyncDesc.h"
#include "teleMainBLRpcAsyncDesc.h"
#include "tlmVINConflictTester.h"

/**
 * \brief  Constructor.
 *
 * TestID: 
 *
 * \param - none
 *
 * \return - none
 */
teleMainBL::teleMainBL()
{
    //#[ operation teleMainBL()
    memset( &mDataPool, 0, sizeof(mDataPool) );
    mDataPool.connStatus = CS_UNKNOWN;
    mDataPool.devStatus = DS_UNKNOWN;
    mDataPool.netStatus.access_type = TYPE_NONE;
    InitializeCriticalSection( &mCSDataPoolWR );
    //#]
}

/**
 * \brief  Destructor.
 *
 * \param - none
 *
 * \return - none
 */
teleMainBL::~teleMainBL() {
    //#[ operation ~teleMainBL()
    //#]
}

/**
 * \brief  This function retrieve or create new instance of teleMainBL
 *
 * TestID: 
 *
 * \param - none
 *
 * \return mpInstance - created instance
 */
teleMainBL& teleMainBL::getInstance()
{
//	LOG_PRINT(DPCA_TELE_MAIN_INFO,"[teleMainBL]: getInstance \n");
 	static teleMainBL instance;
	return instance;
}

/**
 * \brief  Initialize the teleMainBL.
 *
 * TestID: 
 *
 * \param - none
 *
 * \return - none
 */
void teleMainBL::initialize(void)
{
	LOG_PRINT(DPCA_TELE_MAIN_INFO,"[teleMainBL]:teleMainBL::initialize\n");
    teleGenHMIMsgHandler::getInstance().initialize();
    tlmServiceMsgHandler::getInstance().initialize();
}


/**
 * \brief  This function perform the syncronize call of process handler class.
 *
 * \param p [in] Pointer of the data structure of RPC call
 *
 * \return - none
 */
void teleMainBL::__SyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __SyncCall(RPC_IOCTL_PTR)
    teleMainBLRpcSyncDesc desc(p);
    desc.send(p->ac->mExecutionThread);
    //#]
}

/**
 * \brief  This function perform the Asyncronize call of process handler class.
 *
 * TestID: 
 *
 * \param p [in]  Pointer of the data structure of RPC call
 *
 * \return - none
 */
void teleMainBL::__AsyncCall(RPC_IOCTL_PTR p) {
    //#[ operation __AsyncCall(RPC_IOCTL_PTR)
    teleMainBLRpcAsyncDesc* pDesc = new teleMainBLRpcAsyncDesc(p);
    pDesc->send(p->ac->mExecutionThread);
    //#]
}

void teleMainBL::sendAsyncRpcCall(uc8_t funID,
                                LPVOID inBuffer, 
                                uint8_t inBufferSize, 
                                LPVOID outBuffer, 
                                uint8_t outBufferSize)
{
    s_RPC_IOCTL lRpc;

	/* RPC IOCTL stucture */
	lRpc.ac = this;
	lRpc.dmFuncID = funID;
	lRpc.lpInBuffer = inBuffer;
	lRpc.lpOutBuffer =  outBuffer;
	lRpc.nInBufferSize = inBufferSize;
	lRpc.nOutBufferSize = outBufferSize;

	this->AsyncCall(&lRpc);
}
     

/// operation GenHMI_SetAlertPopupStatus()
void teleMainBL::GenHMI_SetAlertPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
	sendAsyncRpcCall(FUNCID_GenericHMI_SET_AlertPopupStatus, inBuffer, inBufferSize);
}

/// operation __GenHMI_SetAlertPopupStatus
void teleMainBL::__GenHMI_SetAlertPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
    S_TLM_SET_AP_STATUS_PACK* lpIDState = reinterpret_cast<S_TLM_SET_AP_STATUS_PACK*>(inBuffer);
    teleGenHMIMsgHandler::getInstance().setAlertPopupStatus( 
            lpIDState->id, 
            lpIDState->status);
}


void teleMainBL::GenHMI_SetQuestionPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
    sendAsyncRpcCall(FUNCID_GenericHMI_SET_QuestionPopupStatus, inBuffer, inBufferSize);
}

void teleMainBL::__GenHMI_SetQuestionPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
    S_TLM_SET_QP_STATUS_PACK* lpIDState = reinterpret_cast<S_TLM_SET_QP_STATUS_PACK*>(inBuffer);
    teleGenHMIMsgHandler::getInstance().setQuestionPopupStatus( 
            lpIDState->id, 
            lpIDState->button,
            lpIDState->status);
}

void teleMainBL::GenHMI_SetListPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
    sendAsyncRpcCall(FUNCID_GenericHMI_SET_ListPopupStatus, inBuffer, inBufferSize);
}

void teleMainBL::__GenHMI_SetListPopupStatus(LPVOID inBuffer, uint8_t inBufferSize){
    S_TLM_SET_LP_STATUS_PACK* lpIDState = reinterpret_cast<S_TLM_SET_LP_STATUS_PACK*>(inBuffer);
    teleGenHMIMsgHandler::getInstance().setListPopupStatus( 
            lpIDState->id, 
            lpIDState->index,
            lpIDState->status);
}


void teleMainBL::GenHMI_PostATBMessage(LPVOID inBuffer, uint8_t inBufferSize){
    sendAsyncRpcCall(FUNCID_GenericHMI_POST_ATBMessage, inBuffer, inBufferSize);
}

void teleMainBL::__GenHMI_PostATBMessage(LPVOID inBuffer, uint8_t inBufferSize){
    char ** buffAdd = reinterpret_cast<char **>(inBuffer);
    if(buffAdd){
        teleGenHMIMsgHandler::getInstance().parseXML( *buffAdd );
    }
}

//VIN Conflict
void teleMainBL::Admin_DetectVINConflict(E_VIN_TRIGGER triggerType)
{
    //FUNCID_Admin_SET_TestVINConflict
    sendAsyncRpcCall( FUNCID_Admin_SET_TestVINConflict, &triggerType,  sizeof(E_VIN_TRIGGER) );
}

void teleMainBL::__Admin_DetectVINConflict(LPVOID inBuffer, uint8_t inBufferSize)
{
    tlmVINConflictTester conflictTester;
    uint8_t * pCode = reinterpret_cast<uint8_t *>(inBuffer);

    if( pCode ){
        switch( *pCode ){
            case VIN_SET_USER_ON:
            {
                conflictTester.OnSetUserOn();
                break;
            }
            case VIN_GENERAL:
            {
                conflictTester.OnUpdateGeneralVIN();
                break;
            }
            case VIN_SERVER:
            {
                conflictTester.OnUpdateServerVIN();
                break;
            }
            default:
            {
                LOG_PRINT(DPCA_TELE_MAIN_ERROR,"[teleMainBL]:Admin : Invalid parameter\n");
            }    
        };
    }
    
}


///Data Pool Interface
void teleMainBL::setDataConnStatus(const E_CONN_STATUS & status)
{
    mDataPool.connStatus = status;
}

void teleMainBL::setNetworkStatus(const S_TLM_NET_STATUS & status)
{
    EnterCriticalSection(&mCSDataPoolWR);
    mDataPool.netStatus = status;
    LeaveCriticalSection(&mCSDataPoolWR);
}

void teleMainBL::setDevStatus(const E_DEV_STATUS & status)
{
    mDataPool.devStatus = status;
}

void teleMainBL::getDataConnStatus(E_CONN_STATUS * status)
{
    *status = mDataPool.connStatus;
}

void teleMainBL::getNetworkStatus(S_TLM_NET_STATUS * status)
{
    EnterCriticalSection(&mCSDataPoolWR);
    *status = mDataPool.netStatus;
    LeaveCriticalSection(&mCSDataPoolWR);
}

void teleMainBL::getDevStatus(E_DEV_STATUS * status)
{
    *status = mDataPool.devStatus;
}


